﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using Domino;

namespace WorkTool
{
	public partial class LotusTool : UserControl
	{
		public LotusTool()
		{
			InitializeComponent();
		}
		private static string LotusPassword = "";
		private List<NotesDocument> nDocs;

		private void LotusTool_Load(object sender, EventArgs e)
		{
			Write("Lotus Tool Control - 04/08/09, by Kevin Connolly");
			Write("Adapted from LotusHeaderGetter console app, 03/19/09");
			Write("Enter Lotus password via command \"auth\".");
			Write("Type ? for Help");
		}
		private void button1_Click(object sender, EventArgs e)
		{
			DoCommand(textBox2.Text.Trim());
			textBox2.Text = "";
			textBox2.Focus();
		}

		bool DoCommand(string command)
		{
			string[] args = command.Split(' ');
			try
			{
				switch (args[0].ToLower())
				{
					default:
						Write("Bad command or file name");
						break;
					case "m":
					case "messages":
						cmdGetMessages();
						break;
					case "headers":
					case "h":
						switch (args.Length)
						{
							case 3:
								cmdGetHeader(int.Parse(args[1]), args[2]);
								break;
							case 2:
								cmdGetMessage(int.Parse(args[1]), true);
								break;
						}
						break;
					case "body":
					case "b":
						cmdGetMessage(int.Parse(args[1]), false);
						break;
					case "cls":
					case "clear":
					case "c":
						textBox1.Text = "";
						break;
					case "help":
					case "?":
						cmdHelp();
						break;
					case "auth":
						GetString gs = new GetString("Enter your Lotus password:", true);
						if (gs.ShowDialog() == DialogResult.OK && gs.TextValue.Trim().Length > 0)
						{
							LotusPassword = gs.TextValue;
							Write("Lotus password entered.");
						}
						else Write("Lotus password entry cancelled.");
						break;
				}
			}
			catch (Exception ex)
			{
				Write("Error: " + ex.Message);
			}

			return false;
		}
		void cmdGetMessages()
		{
			nDocs = GetMessages();
			if (nDocs == null)
			{
				Write("No messages were retrieved.");
				return;
			}
			for (int i = 0; i < nDocs.Count; i++)
			{
				string str = i.ToString() + ": " + nDocs[i].GetFirstItem("From").Text;
				if (str.Length <= 60)
					str += nDocs[i].GetFirstItem("Subject").Text;
				if (str.Length >= 80) str = str.Substring(0, 79);
				Write(str);
			}

		}
		void cmdGetMessage(int msg, bool HeadersOnly)
		{
			NotesDocument nDoc = nDocs[msg];
			Write("Dumping message " + msg.ToString() + "...");
			Write("───────────────────────────────────────────────────────────────────────────────");

			Object[] ni = (Object[])nDoc.Items;
			for (int i = 0; i < ni.Length; i++)
			{
				NotesItem item = (NotesItem)ni[i];
				if (item == null || (item.Name == "Body" && HeadersOnly) || (item.Name != "Body" && !HeadersOnly))
					continue;
				try
				{
					Console.Write("Header #" + i.ToString() + ": " + item.Name + " | " + item.Text.Replace('\t', ' '));
				}
				catch
				{
					Write("(Error)");
				}
			}

		}
		void cmdGetHeader(int msg, string HeaderName)
		{
			NotesDocument nDoc = nDocs[msg];
			try
			{
				Write(nDoc.GetFirstItem(HeaderName).Text);
			}
			catch (Exception ex)
			{
				Write("Recoverable error: " + ex.Message);
			}
			finally
			{
				Console.Write("\r\n");
			}
		}
		void cmdHelp()
		{
			Write(
				"auth: Authenticate Lotus password\r\n" +
				" - Usage: auth\r\n" +
				" - Note: You will be prompted for the password.\r\n" +
				"m, messages: Retrieve all messages\r\n" +
				" - Usage: m\r\n" +
				"headers, h: Retrieve message headers\r\n" +
				" - Usage: h x (x = message number)\r\n" +
				" - Usage: h x y (x = message number; y = header name (i.e. \"From\"))\r\n" +
				"body, b: Retrieve message body\r\n" +
				" - Usage: b x (x = message number)\r\n" +
				"cls, clear, c: Clear the screen\r\n" +
				" - Usage: c\r\n" +
				"help, ?: This help screen\r\n" +
				" - Usage: ?\r\n"
				);

		}

		void Write(string message) 
		{
			if (textBox1.Text.Length > 8192) 
				textBox1.Text = textBox1.Text.Substring(textBox1.Text.Length - 4096);
			textBox1.Text += message + "\r\n";
			textBox1.SelectionStart = textBox1.Text.Length;
			textBox1.ScrollToCaret();
		}

		#region Lotus Interop

		private List<NotesDocument> GetMessages()
		{
			try
			{
				// Open connection to Lotus
				List<NotesDocument> nDocs;
				DateTime dStarted = DateTime.Now;
				NotesDatabase LotusDB = InitLotusSession();
				if (LotusDB == null) return null;

				// Message retrieval preparation
				int CurMessage = 0;
				nDocs = new List<NotesDocument>();
				NotesView mailView = LotusDB.GetView("($Inbox)");
				int NumMessages = mailView.EntryCount;
				NotesDocument nDoc = mailView.GetLastDocument();

				// Message retrieval loop
				while (nDoc != null && DateTime.Now - dStarted < TimeSpan.FromSeconds(30))
				{
					CurMessage++;
					nDocs.Add(nDoc);
					nDoc = mailView.GetPrevDocument(nDoc);
				}
				return nDocs;
			}
			catch
			{
			}
			return null;
		}
		private NotesDatabase InitLotusSession()
		{
			string NotesServer = ConfigurationManager.AppSettings["LotusServer"];
			string NotesDatabase = ConfigurationManager.AppSettings["LotusDatabase"];

			if (string.IsNullOrEmpty(NotesServer))
			{
				GetString gs = new GetString("I don't know the NotesServer. Enter it now:");
				if (gs.ShowDialog() == DialogResult.OK) NotesServer = gs.TextValue;
			}
			if (string.IsNullOrEmpty(NotesServer))
			{
				MessageBox.Show("Can't connect to Lotus server without knowing what server to connect to");
				return null;
			}
			if (string.IsNullOrEmpty(NotesDatabase))
			{
				GetString gs = new GetString("I don't know the Notes Database to open. Enter it now:");
				if (gs.ShowDialog() == DialogResult.OK) NotesDatabase = gs.TextValue;
			}
			if (string.IsNullOrEmpty(NotesDatabase))
			{
				MessageBox.Show("Can't connect to Lotus server without knowing what database to use");
				return null;
			}

			try
			{
				NotesSession LotusSession;
				try
				{
					LotusSession = new NotesSessionClass();
					LotusSession.Initialize(LotusPassword);
				}
				catch (Exception ex)
				{
					Write(ex.Message);
					return null;
				}

				// init database
				NotesDatabase LotusDB = LotusSession.GetDatabase(NotesServer, NotesDatabase, false);
				if (LotusDB == null)
				{
					Write("Unable to locate Lotus database");
					return null;
				}
				return LotusDB;
			}
			catch (Exception ex)
			{
				Write(ex.Message);
				return null;
			}
		}


		#endregion Lotus Interop
	}
}
